package com.taikang.common.util.config;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidParameterException;
import java.util.Iterator;
import java.util.Properties;

import org.apache.log4j.Logger;

/**
 * @author liucr
 */
public class SystemGlobals implements VariableStore {
	
	public static void main(String args[]){
		System.out.println(SystemGlobals.getValue("remittance"));
		
	}
	
	private static SystemGlobals globals = new SystemGlobals();

	private Properties defaults = new Properties();

	private VariableExpander expander = new VariableExpander(this, "${", "}");

	@SuppressWarnings("unused")
	private static final Logger logger = Logger.getLogger(SystemGlobals.class);

	static {

		SystemGlobals.initGlobals("/SystemGlobals.properties");
	}

	private SystemGlobals() {
	}

	/**
	 * Initialize the global configuration
	 * 
	 * @param appPath
	 *            The application path (normally the path to the webapp base dir
	 * @param mainConfigurationFile
	 * 
	 */
	public static void initGlobals(String mainConfigurationFile) {
		globals = new SystemGlobals();
		globals.buildSystem(mainConfigurationFile);
	}

	public static void reset() {
		globals.defaults.clear();
	}

	private void buildSystem(String mainConfigurationFile) {
		if (mainConfigurationFile == null) {
			throw new InvalidParameterException("defaultConfig could not be null");
		}

		this.defaults = new Properties();
		SystemGlobals.loadDefaults(mainConfigurationFile);

	}

	/**
	 * Load system defaults
	 */
	public static void loadDefaults(String mainConfigurationFile) {
		try {
			InputStream input = SystemGlobals.class.getClassLoader().getResourceAsStream(mainConfigurationFile);

			if (input == null) {
				input = SystemGlobals.class.getResourceAsStream(mainConfigurationFile);
			}
			globals.defaults.load(input);
			input.close();
			globals.expander.clearCache();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Gets the value of some property
	 * 
	 * @param field
	 *            The property name to retrieve the value
	 * @return String with the value, or <code>null</code> if not found
	 * @see #setValue(String, String)
	 */
	public static String getValue(String field) {
		return globals.getVariableValue(field);
	}

	/**
	 * Retrieve an integer-valued configuration field
	 * 
	 * @param field
	 *            Name of the configuration option
	 * @return The value of the configuration option
	 * @exception NullPointerException
	 *                when the field does not exists
	 */
	public static int getIntValue(String field) {
		return Integer.parseInt(getValue(field));
	}

	/**
	 * Retrieve an boolean-values configuration field
	 * 
	 * @param field
	 *            name of the configuration option
	 * @return The value of the configuration option
	 * @exception NullPointerException
	 *                when the field does not exists
	 */
	public static boolean getBoolValue(String field) {
		return "true".equals(getValue(field));
	}

	/**
	 * Return the value of a configuration value as a variable. Variable
	 * expansion is performe on the result.
	 * 
	 * @param field
	 *            The field name to retrieve
	 * @return The value of the field if present or null if not
	 */

	public String getVariableValue(String field) {
		String preExpansion = this.defaults.getProperty(field);

		if (preExpansion == null) {
			return null;
		}

		return expander.expandVariables(preExpansion);
	}

	/**
	 * Getst the complete path to the application's root dir
	 * 
	 * @return String with the path
	 * @see #setApplicationPath
	 */
	public static String getApplicationPath() {
		return getValue(ConfigKeys.APPLICATION_PATH);
	}

	/**
	 * Retrieve an iterator that iterates over all known configuration keys
	 * 
	 * @return An iterator that iterates over all known configuration keys
	 */
	@SuppressWarnings("unchecked")
	public static Iterator fetchConfigKeyIterator() {
		return globals.defaults.keySet().iterator();
	}

	public static Properties getConfigData() {
		return new Properties(globals.defaults);
	}
}